home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS05.ADF / IFF / iffcheck.c < prev    next >
C/C++ Source or Header  |  1986-04-20  |  7KB  |  217 lines

  1.  
  2. /*--------------------------------------------------------------------- */
  3. /* IFFCheck.C  Print out the structure of an IFF-85 file,      1/23/86  */
  4. /* checking for structural errors.                     */
  5. /*                                           */
  6. /* DO NOT USE THIS AS A SKELETAL PROGRAM FOR AN IFF READER!      */
  7. /* See ShowILBM.C for a skeletal example.                   */
  8. /*                                                                      */ 
  9. /* By Jerry Morrison and Steve Shaw, Electronic Arts.                   */ 
  10. /* This software is in the public domain.                               */ 
  11. /*                                                                      */ 
  12. /* This version for the Commodore-Amiga computer.                       */
  13. /*                                                                      */ 
  14. /* ---------------------------------------------------------------------*/
  15. #include "iff/iff.h"
  16.  
  17.  
  18. /* ---------- IFFCheck -------------------------------------------------*/
  19. /* [TBD] More extensive checking could be done on the IDs encountered in the
  20.  * file. Check that the reserved IDs "FOR1".."FOR9", "LIS1".."LIS9", and
  21.  * "CAT1".."CAT9" aren't used. Check that reserved IDs aren't used as Form
  22.  * types. Check that all IDs are made of 4 printable characters (trailing
  23.  * spaces ok). */
  24.  
  25. typedef struct {
  26.     ClientFrame clientFrame;
  27.     int levels;          /* # groups currently nested within.*/
  28.     } Frame;
  29.  
  30. char MsgOkay[] = { "----- (IFF_OKAY) A good IFF file." };
  31. char MsgEndMark[] = {"----- (END_MARK) How did you get this message??" };
  32. char MsgDone[] = { "----- (IFF_DONE) How did you get this message??" };
  33. char MsgDos[] = { "----- (DOS_ERROR) The DOS gave back an error." };
  34. char MsgNot[] = { "----- (NOT_IFF) not an IFF file." };
  35. char MsgNoFile[] = { "----- (NO_FILE) no such file found." };
  36. char MsgClientError[] = {"----- (CLIENT_ERROR) IFF Checker bug."};
  37. char MsgForm[] = { "----- (BAD_FORM) How did you get this message??" };
  38. char MsgShort[] = { "----- (SHORT_CHUNK) How did you get this message??" };
  39. char MsgBad[] = { "----- (BAD_IFF) a mangled IFF file." };
  40.  
  41. /* MUST GET THESE IN RIGHT ORDER!!*/
  42. char *IFFPMessages[-(int)LAST_ERROR+1] = {
  43.     /*IFF_OKAY*/  MsgOkay,
  44.     /*END_MARK*/  MsgEndMark,
  45.     /*IFF_DONE*/  MsgDone,
  46.     /*DOS_ERROR*/ MsgDos,
  47.     /*NOT_IFF*/   MsgNot,
  48.     /*NO_FILE*/   MsgNoFile,
  49.     /*CLIENT_ERROR*/ MsgClientError,
  50.     /*BAD_FORM*/  MsgForm,
  51.     /*SHORT_CHUNK*/  MsgShort,
  52.     /*BAD_IFF*/   MsgBad
  53.     };
  54.  
  55. /* FORWARD REFERENCES */
  56. extern IFFP GetList(GroupContext *);
  57. extern IFFP GetForm(GroupContext *);
  58. extern IFFP GetProp(GroupContext *);
  59. extern IFFP GetCat (GroupContext *);
  60.  
  61. void IFFCheck(name)  char *name; {
  62.     IFFP iffp;
  63.     BPTR file = Open(name, MODE_OLDFILE);
  64.     Frame frame;
  65.  
  66.     frame.levels = 0;
  67.     frame.clientFrame.getList = GetList;
  68.     frame.clientFrame.getForm = GetForm;
  69.     frame.clientFrame.getProp = GetProp;
  70.     frame.clientFrame.getCat  = GetCat ;
  71.  
  72.     printf("----- Checking file '%s' -----\n", name);
  73.     if (file == 0)
  74.      iffp = NO_FILE;
  75.     else
  76.      iffp = ReadIFF(file, (ClientFrame *)&frame);
  77.  
  78.     Close(file);
  79.     printf("%s\n", IFFPMessages[-iffp]);
  80.     }
  81.  
  82. main(argc, argv)   int argc;  char **argv; {
  83.     if (argc != 1+1) {
  84.      printf("Usage: 'iffcheck filename'\n");
  85.      exit(0);
  86.      }
  87.     IFFCheck(argv[1]);
  88.     }
  89.  
  90. /* ---------- Put... ---------------------------------------------------*/
  91.  
  92. PutLevels(count)   int count; {
  93.     for ( ;  count > 0;  --count) {
  94.      printf(".");
  95.      }
  96.     }
  97.  
  98. PutID(id)  ID id; {
  99.     printf("%c%c%c%c",
  100.         (char)((id>>24L) & 0x7f),
  101.         (char)((id>>16L) & 0x7f),
  102.         (char)((id>>8)   & 0x7f),
  103.         (char)(id        & 0x7f) );
  104.     }
  105.  
  106. PutN(n)   int n; {
  107.     printf(" %d ", n);
  108.     }
  109.  
  110. /* Put something like "...BMHD 14" or "...LIST 14 PLBM". */
  111. PutHdr(context)  GroupContext *context; {
  112.     PutLevels( ((Frame *)context->clientFrame)->levels );
  113.     PutID(context->ckHdr.ckID);
  114.     PutN(context->ckHdr.ckSize);
  115.  
  116.     if (context->subtype != NULL_CHUNK)
  117.      PutID(context->subtype);
  118.  
  119.     printf("\n");
  120.     }
  121.  
  122. /* ---------- AtLeaf ---------------------------------------------------*/
  123.  
  124. /* At Leaf chunk.  That is, a chunk which does NOT contain other chunks.
  125.  * Print "ID size".*/
  126. IFFP AtLeaf(context)  GroupContext *context; {
  127.  
  128.     PutHdr(context);
  129.     /* A typical reader would read the chunk's contents, using the "Frame"
  130.      * for local data, esp. shared property settings (PROP).*/
  131.     /* IFFReadBytes(context, ...buffer, context->ckHdr->ckSize); */
  132.     return(IFF_OKAY);
  133.     }
  134.  
  135. /* ---------- GetList --------------------------------------------------*/
  136. /* Handle a LIST chunk.  Print "LIST size subTypeID".
  137.  * Then dive into it.*/
  138. IFFP GetList(parent)  GroupContext *parent; {
  139.     Frame newFrame;
  140.  
  141.     newFrame = *(Frame *)parent->clientFrame;  /* copy parent's frame*/
  142.     newFrame.levels++;
  143.  
  144.     PutHdr(parent);
  145.  
  146.     return( ReadIList(parent, (ClientFrame *)&newFrame) );
  147.     }
  148.  
  149. /* ---------- GetForm --------------------------------------------------*/
  150. /* Handle a FORM chunk.  Print "FORM size subTypeID".
  151.  * Then dive into it.*/
  152. IFFP GetForm(parent)   GroupContext *parent; {
  153.     /*CompilerBug register*/ IFFP iffp;
  154.     GroupContext new;
  155.     Frame newFrame;
  156.  
  157.     newFrame = *(Frame *)parent->clientFrame;  /* copy parent's frame*/
  158.     newFrame.levels++;
  159.  
  160.     PutHdr(parent);
  161.  
  162.     iffp = OpenRGroup(parent, &new);
  163.     CheckIFFP();
  164.     new.clientFrame = (ClientFrame *)&newFrame;
  165.  
  166.     /* FORM reader for Checker. */
  167.     /* LIST, FORM, PROP, CAT already handled by GetF1ChunkHdr. */
  168.     do {if ( (iffp = GetF1ChunkHdr(&new)) > 0 )
  169.          iffp = AtLeaf(&new);
  170.      } while (iffp >= IFF_OKAY);
  171.  
  172.     CloseRGroup(&new);
  173.     return(iffp == END_MARK ? IFF_OKAY : iffp);
  174.     }
  175.  
  176. /* ---------- GetProp --------------------------------------------------*/
  177. /* Handle a PROP chunk.  Print "PROP size subTypeID".
  178.  * Then dive into it.*/
  179. IFFP GetProp(listContext)  GroupContext *listContext; {
  180.     /*CompilerBug register*/ IFFP iffp;
  181.     GroupContext new;
  182.  
  183.     PutHdr(listContext);
  184.  
  185.     iffp = OpenRGroup(listContext, &new);
  186.     CheckIFFP();
  187.  
  188.     /* PROP reader for Checker. */
  189.     ((Frame *)listContext->clientFrame)->levels++;
  190.  
  191.     do {if ( (iffp = GetPChunkHdr(&new)) > 0 )
  192.          iffp = AtLeaf(&new);
  193.      } while (iffp >= IFF_OKAY);
  194.  
  195.     ((Frame *)listContext->clientFrame)->levels--;
  196.  
  197.     CloseRGroup(&new);
  198.     return(iffp == END_MARK ? IFF_OKAY : iffp);
  199.     }
  200.  
  201. /* ---------- GetCat ---------------------------------------------------*/
  202. /* Handle a CAT chunk.  Print "CAT size subTypeID".
  203.  * Then dive into it.*/
  204. IFFP GetCat(parent)  GroupContext *parent;  {
  205.     IFFP iffp;
  206.  
  207.     ((Frame *)parent->clientFrame)->levels++;
  208.  
  209.     PutHdr(parent);
  210.  
  211.     iffp = ReadICat(parent);
  212.  
  213.     ((Frame *)parent->clientFrame)->levels--;
  214.     return(iffp);
  215.     }
  216.  
  217.